package com.kgcx.pay.util;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.kgcx.common.eum.CommonDataEeum;
import com.kgcx.common.eum.OrderEnum;
import com.kgcx.common.utils.MoneyUtil;
import lombok.extern.slf4j.Slf4j;


/**
 * 第三方 支付宝支付
 * @author qinze
 *
 */
@Slf4j
@Service
public class AliPayUtil {

	/**
	 * 司机端
	 */
	private static final String DRIVER_APP_ID = "2017120400376627";

	private static final String DRIVER_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqrzIK/R89N8A1P/as1gcRO8UW4LWDWRtmaKRv+TZnW3p7eE+Kny3RcFZDj+/MHVihH0GcWtzkBpDjJcCL/82XD305JskFWD1R0EmAIsStouGpFBGpPKK0r+ir7eqdCL1mDK1FZsmTZYZjps6XWHypnJ9kNJ10YQYLH8undGkz1whHBsQtMQXezIFTzY6Va8xOGMuUaB+0mzJxSbrdHQ+YT4AbYEkGB2LD4++JQsqMVvEBi3DuDNVgfFXfN2O8XAvziJTiz2gkRW5D+Lz56pBQ2hPnl3wQ6BpfrfT0Vz+3xetLYKlWbTvNKhgV+7eAWELpZb06rLY1m9pDbdWQRDWQIDAQAB";// 支付宝公钥

	private static final String DRIVER_PRIVATE_KEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCkqcQI9GRNBEEPUgulFpu3qXJofNN4Nt9BBXL0PY4/9wlbjP9LATuTYrdFGaGcqvPC08mJhpLvaonkSAbUVkRoM43fWzBoXeSfwKV0TFjaXUsAApya2NgwCMDquMO5vVQPzRmC5LGY967BDwz19xvFGn//zHiWkpLazxZWikwmBuwmDJAV5dPkfGGcUm1Jeg/O4HgrFC8X3qFaLt6GZUyaRMdmK0wUqZd39jPb857K9k7c4jeNQJBaEMPYZoe45f6BqX5TdrYHMuM9gScZR0PxpJM3bT8CzW7HwOd8edKHotfLWdZ3ZuwosWENtMsYVK50JdzstGQKoGnyKMnXG+JVAgMBAAECggEAU1pYkMvd5hqsMGww1t3t73fIIVpm1ei49LokabyrQHf19bEXHkm+dao36bPC2oKzKEF7OLG1uZotuTA4vM36jODkBVes1ngJHlEvsAJhzBADwjqQOdZhAVe9CFSFR4Wugt0o99h6ilt+y92piu0O0qTKfJttw5Lo4fiIb0BMscZnFGe8d9PXA0RnaBHMEenQGIUt0EITtXoD/MzVjXpXMhRFGHNeoyWLGh4i0+q1l0i5Da3jpouQTillJGoh7IiGB1DwlwbjmVrrQyfMfMOoF2mP4ql9EFP/32mV95yxh+ewjGO73epkD3j26B/tQtwa/F200tuSlyiVS/12B8VfYQKBgQDurkHPCL/Spr08qEqpyb6cS4DXzEClpW2wpKd4ZfxzxDJTo/2kNC4iFiQz0/4W/o+mFaLugqJ6LUl7m4RPQLbw8LIWXcKQgzWvCP7HXeDvzhH4g/O5z34ZcB1FGAbgDsOx7WqyTNo1b7t8OoeZlg96e8rGqTdpamQhK2+BtTxsXQKBgQCwnI45xC9juGZQEAJkTQL2HW82JbVfbPL0YDz0Ij832xmI44ydwaEy4fIf/jlo8oLadHyNkdmpDFEZaiW/FNQTt7o4sg5JpKBkFhznF94F1minflmw9IzDnDK4qT7fwyp5cgWz6izjdveuYhsOaE8FEI6/nd7MsNUpwjQjcg+uWQKBgFoVPNNGCxgXRG8DWYKxmRZmTM+l0HR0dmzoCCkh3OFYmGIHD/EMnKjS0IEbLthA5biai+8XMPmJ5CUZ8hrzYtiXD6/vXUKrsvRIIdjfLslzbkbsjm1/yakSLonoYpfoGqYp5E49QVJPxGRDtvAZuefRlxvZvAc2V2pJeYFsBM0lAoGAVL/7vBq5xvehGUBldW5DQoljaa90tsMYX06jUV/xyEL6oObY/ocBbOJiBxo+wG7Hfj8x2dmogmenrzNxw50iHAgpc7V2B77ZPM4jtn2MjG6UL/QA5FqmBeQ5rsWAp24HPtoJhImWWt0nA+aOJz7E1KBab/c5CC6/S9emn2/HuJkCgYEAtuar9H3bzPtaZSP+ThSPlu949yZp73NTSznvwwek5VUC3PEy4JNRs0XMI/vfg7/vV4rSaaxpLRpKnvYezE45ZhLgn9/gmscPlQmrWJ+koWnGZGhRBhifgGwATLo2SQrDX9rRij+5aAg2Q+zyjHzL7LqgHmcflNH0fzaIFaiYNmI=";// 支付宝私钥

	/**
	 * 乘客端口
	 */
	private static final String USER_APP_ID = "2017121300689240";

	private static final String USER_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwqrzIK/R89N8A1P/as1gcRO8UW4LWDWRtmaKRv+TZnW3p7eE+Kny3RcFZDj+/MHVihH0GcWtzkBpDjJcCL/82XD305JskFWD1R0EmAIsStouGpFBGpPKK0r+ir7eqdCL1mDK1FZsmTZYZjps6XWHypnJ9kNJ10YQYLH8undGkz1whHBsQtMQXezIFTzY6Va8xOGMuUaB+0mzJxSbrdHQ+YT4AbYEkGB2LD4++JQsqMVvEBi3DuDNVgfFXfN2O8XAvziJTiz2gkRW5D+Lz56pBQ2hPnl3wQ6BpfrfT0Vz+3xetLYKlWbTvNKhgV+7eAWELpZb06rLY1m9pDbdWQRDWQIDAQAB";// 支付宝公钥

	private static final String USER_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCnkuO++9NX21SgCwyyqaS2StSEA3rKSRG8/2tb6ZSsfzWrjiD2Jo7JXXArwMVMv0i6HWhSniixdDLzyFZRT7chuD45FeijSol9LIE+I6jNHy/ULlazbvXXk4/y8tmJq8ga776JoWfGOYjzV9VQvrlQ1jMArQrVgoShdhnQf+iYGDMC4r5xj9k5DX9ujx37TUgv6GFOghM4o2a2oHkxRentkGBwVRhV8ByG7oM03oyMckXM8YZgssQrS862ThkXSZiqksWYFwEOS7+5ZcJIf7JO+etdqrJ5uE3uE3a0lNHn8V89w4JGafDlh2WI/mosmRQuVv41eXLjKXUoJwRaFzbRAgMBAAECggEAMZ/+cgCBhfMeDIc5K2+xp4phhPbC1kTtS9sYIA/8R1kku7lLaZnhjyBsp4he5WuATh2HV3Ae/O48aJVbepjw0ruNMbqbOkBIlxkm7RACXTxvHZbbdifWBhFc/8WLRonoqJF3C6sQ4FMJi4bnVRImLxo/4GNeYfxU6rveyTAX4XJObTDMgaCDczKrjG0l8du5teCkv5zigXIwtPU/LXmlhWKfuFQuJC7Kp6BsQWL04hr3YP6nQgPRhgG36Rn82HcufeULpGQMipK4bOZL4JvSMsPxlJZJvnVn5EAOoMbQuaHrGds1DyRc7hl8XYlYrxtrMRcpUm+1n5KBuHMyxEC9QQKBgQDVp8yUvaXuhYLx5P+qyKNQ5SxjtLRsGOq87JqNjXlklioW9f78SC8WA/QJIj/YYdK6vN4HyxM1/crnalflzwDTmsGUdnLcwX8TIQ69EXBjFjLsXfhhlxKXzeEwzae04I+ZVi/oGNxFtrfJJwFBGQfzKCgWCmfnadbC3HGCuFo3BwKBgQDIyQ1hzy2Yjhrs8UffsG0IJ5Bf8f/apDJosUCJd5LdkmKhwxicDIc2wblsVLAjUk1SIiWJIMSnKalzthfjr27gpFj6+pn/zppnzHxCieZUTjkdfPRlS1Z8K+kAdOOYskuM+kbLozF+MoZzWNaq+Emoxf5wlste89WHTwVYYRyVZwKBgQDLYTTUbgczG3J/sx5Qwzb7fXwY2V5Z/AoPlya0EnT49BzSyI5WNpxj15WI0Ep4Pv5q9fhg8MWzwohQa6GKR9eglpMpMOu8CpFdcz1lauFR4ULOT9FtjHKNgNSZMVswSgdHzoxB4tBjqEAgwflmr14q8BHgkT1BQzXFPjTrW3O9JwKBgQCNsJOo+jMK/P0zR/GYgT/wCTtw+a279TM9fhg06hTSF4NS9AJh3NVuZrcbI4hI5MN7um0Sn/UmodfauB2TpzFvhYrlUgNq6bk8lqj5q6bGx4y2qn8tHEUjyzjaAaK7FtcJ3XQoMDm0/KK0s3SJoj0YxOARQ9iwYRHGMpVrENzC8QKBgGsUIVl29cvk0ExQqCKzb9JrK3rmwQC7ieNHpXDQgl0clXmHJK/2jqjfnh/secaKpqu3R77dC23vRtpAVgioZWuczTEA/0pE+VhgnJDgWJpdawH02PZaz09MfOEEK7SiRd8CklDRg6gKXyux2mObB24BPqpBX5rcYxX7yItFGS15";// 支付宝私钥
	
	private static final String SERVER_URL = "https://openapi.alipay.com/gateway.do";// 支付宝预支付地址
	
	private AlipayClient alipayClient;
	
	@PostConstruct
	public void init() {
		try {
			alipayClient = new DefaultAlipayClient(SERVER_URL, DRIVER_APP_ID, DRIVER_PRIVATE_KEY, "json", "utf-8", DRIVER_PUBLIC_KEY,
					"RSA2"); // 获得初始化的AlipayClient
		} catch (Exception e) {
			log.error("支付宝SDK初始化异常", e);
		}
	}
	
	/**
	 * 对支付宝支付信息进行签名
	 * @param orderId
	 * @param amount
	 * @param noticeUrl
	 * @param payOrderNo
	 * @param payClientType 支付端类型
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public PayPreInfoBean alipayPayInfo(String orderId, String amount, String noticeUrl,String payOrderNo,int payClientType) {
		PayPreInfoBean payPreInfoBean = new PayPreInfoBean();
		try {
			String nowtime = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
			String bizContent = "{\"timeout_express\":\"5m\"," + "\"out_trade_no\":\"" + payOrderNo + "\","
					+ "\"total_amount\":\"" + amount + "\"," + "\"subject\":\"" + "交易支付" + "\","
					+ "\"product_code\":\"QUICK_MSECURITY_PAY\"" + "}";
			Map<String, String> sParaTemp = new HashMap<String, String>();
			if (CommonDataEeum.PAY_TYEP_SMALL_ROUTINE.getCode() == payClientType 
					|| CommonDataEeum.PAY_TYEP_PASSENGER.getCode() == payClientType) {
				sParaTemp.put("app_id", USER_APP_ID);
			} else if (CommonDataEeum.PAY_TYEP_DRIVER.getCode() == payClientType) {
				sParaTemp.put("app_id", DRIVER_APP_ID);
			} 
			sParaTemp.put("charset", "utf-8");
			sParaTemp.put("format", "json");
			sParaTemp.put("biz_content", bizContent);
			sParaTemp.put("method", "alipay.trade.app.pay");
			sParaTemp.put("notify_url", noticeUrl);
			sParaTemp.put("timestamp", nowtime);
			sParaTemp.put("version", "1.0");
			sParaTemp.put("sign_type", "RSA2");
			String requestUrl = createLinkString(sParaTemp);
			String sign ="";
			if (CommonDataEeum.PAY_TYEP_SMALL_ROUTINE.getCode() == payClientType 
					|| CommonDataEeum.PAY_TYEP_PASSENGER.getCode() == payClientType) {
				 sign = AlipaySignature.rsaSign(requestUrl, USER_PRIVATE_KEY, "utf-8", "RSA2");
			} else if (CommonDataEeum.PAY_TYEP_DRIVER.getCode() == payClientType) {
				 sign = AlipaySignature.rsaSign(requestUrl, DRIVER_PRIVATE_KEY, "utf-8", "RSA2");
			} 
			sign = URLEncoder.encode(sign);
			encodeMap(sParaTemp);
			requestUrl = requestUrl + "&sign=" + sign;
			payPreInfoBean.setPayStatus(true);
			payPreInfoBean.setPayInfo("成功.");
			payPreInfoBean.setData(requestUrl);
			payPreInfoBean.setOrderNum(payOrderNo);
		} catch (Exception e) {
			log.error("支付宝sdk异常", e);
			payPreInfoBean.setPayStatus(false);
		}
		return payPreInfoBean;
	}

	/**
	 * 支付宝支付成功后.会回调该接口
	 * @param valideData
	 * @param amount
	 * @param payType 1 乘客支付 2 司机支付
	 * @return
	 */
	public PayCallbackBean alipayCallback(Map<String, String> valideData, BigDecimal amount,int payType) {
		PayCallbackBean payCallbackBean = new PayCallbackBean();
		try {
			String tradeStatus = valideData.get("trade_status");
			String app_id = valideData.get("app_id");
			String totalAmount = valideData.get("total_amount");
			BigDecimal money = new BigDecimal(MoneyUtil.transferAmountFormat(totalAmount));
			
			if (OrderEnum.PAY_TYPE_DRIVER == payType) {
				if (!app_id.equals(DRIVER_APP_ID)) { // 验证app_id是否为该商户本身
					payCallbackBean.setPayStatus(false);
					payCallbackBean.setPayCallBackInfo("商户号错误");
					return payCallbackBean;
				}
			} else if (OrderEnum.PAY_TYPE_USER == payType) {
				if (!app_id.equals(USER_APP_ID)) { // 验证app_id是否为该商户本身
					payCallbackBean.setPayStatus(false);
					payCallbackBean.setPayCallBackInfo("商户号错误");
					return payCallbackBean;
				}
			} 
			if (amount.compareTo(money) != 0) { // 判断total_amount是否确实为该订单的实际金额（即商户订单创建时的金额）
				payCallbackBean.setPayStatus(false);
				payCallbackBean.setPayCallBackInfo("金额不正确");
				return payCallbackBean;
			} else if (!tradeStatus.equals("TRADE_SUCCESS")) { // 交易通知状态
				payCallbackBean.setPayStatus(false);
				payCallbackBean.setPayCallBackInfo("交易失败");
				return payCallbackBean;
			}
			boolean signVerified = false;
			if (OrderEnum.PAY_TYPE_DRIVER == payType) {
				 signVerified = AlipaySignature.rsaCheckV1(valideData, DRIVER_PUBLIC_KEY, "utf-8", "RSA2"); // 调用SDK验证签名
			} else if (OrderEnum.PAY_TYPE_USER == payType) {
				 signVerified = AlipaySignature.rsaCheckV1(valideData, USER_PUBLIC_KEY, "utf-8", "RSA2"); // 调用SDK验证签名
			}
			if (signVerified) {
				payCallbackBean.setPayStatus(true);
				payCallbackBean.setTransactionId(valideData.get("trade_no"));
				payCallbackBean.setOrderSn(valideData.get("out_trade_no"));
				payCallbackBean.setPayAmount(totalAmount);
			} else {
				payCallbackBean.setPayStatus(false);
				payCallbackBean.setPayCallBackInfo("签名不通过");
				return payCallbackBean;
			}
		} catch (Exception e) {
			log.error("支付宝回掉异常", e);
			payCallbackBean.setPayStatus(false);
			payCallbackBean.setPayCallBackInfo("回掉异常");
			return payCallbackBean;
		}
		return payCallbackBean;
	}


	@SuppressWarnings("deprecation")
	private void encodeMap(Map<String, String> sParaTemp) {
		for (String key : sParaTemp.keySet()) {
			String value = sParaTemp.get(key);
			value = URLEncoder.encode(value);
			sParaTemp.put(key, value);
		}
	}

	public static String createLinkString(Map<String, String> params) {
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String prestr = "";
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key);

			if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
				prestr = prestr + key + "=" + value;
			} else {
				prestr = prestr + key + "=" + value + "&";
			}
		}
		return prestr;
	}
	
	public static void main(String[] args) {
		AliPayUtil aliPayUtil = new AliPayUtil();
		PayPreInfoBean payPreInfoBean = aliPayUtil.alipayPayInfo("nb23444412112", "0.1", "www.baidu.com","9000008",100);
		System.out.println(payPreInfoBean.getData());
	}
}
